package com.apkicon.core;

import java.lang.ref.SoftReference;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.lang.management.MemoryMXBean;
import java.lang.management.ManagementFactory;

/**
 * 内存优化管理器
 * 提供智能缓存、内存监控和自动清理功能
 */
public class MemoryOptimizationManager {
    
    // 软引用缓存，在内存不足时自动清理
    private static final Map<String, SoftReference<Object>> softCache = new ConcurrentHashMap<>();
    
    // 内存监控
    private static final MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
    private static final AtomicLong totalMemoryUsed = new AtomicLong(0);
    private static final AtomicLong cacheHits = new AtomicLong(0);
    private static final AtomicLong cacheMisses = new AtomicLong(0);
    
    // 定时清理任务
    private static final ScheduledExecutorService cleanupExecutor = Executors.newSingleThreadScheduledExecutor();
    
    // 配置参数
    private static final long MAX_CACHE_SIZE = 50 * 1024 * 1024; // 50MB
    private static final long MEMORY_WARNING_THRESHOLD = 80; // 80%内存使用率
    private static final int CLEANUP_INTERVAL_MINUTES = 5;
    
    static {
        // 启动定时清理任务
        startCleanupTask();
    }
    
    /**
     * 获取缓存对象
     */
    public static <T> T getCached(String key, Class<T> type) {
        SoftReference<Object> ref = softCache.get(key);
        if (ref != null) {
            Object obj = ref.get();
            if (obj != null && type.isInstance(obj)) {
                cacheHits.incrementAndGet();
                return type.cast(obj);
            } else {
                // 软引用已被清理
                softCache.remove(key);
            }
        }
        cacheMisses.incrementAndGet();
        return null;
    }
    
    /**
     * 缓存对象
     */
    public static void cacheObject(String key, Object value) {
        if (value != null) {
            // 检查内存使用情况
            if (isMemoryPressureHigh()) {
                System.out.println("⚠️ 内存压力较高，跳过缓存: " + key);
                return;
            }
            
            softCache.put(key, new SoftReference<>(value));
            totalMemoryUsed.addAndGet(estimateObjectSize(value));
            
            // 如果缓存过大，触发清理
            if (totalMemoryUsed.get() > MAX_CACHE_SIZE) {
                cleanupCache();
            }
        }
    }
    
    /**
     * 移除缓存对象
     */
    public static void removeCached(String key) {
        SoftReference<Object> ref = softCache.remove(key);
        if (ref != null) {
            Object obj = ref.get();
            if (obj != null) {
                totalMemoryUsed.addAndGet(-estimateObjectSize(obj));
            }
        }
    }
    
    /**
     * 清理缓存
     */
    public static void cleanupCache() {
        System.out.println("🧹 开始清理缓存...");
        
        int removedCount = 0;
        long freedMemory = 0;
        
        for (Map.Entry<String, SoftReference<Object>> entry : softCache.entrySet()) {
            SoftReference<Object> ref = entry.getValue();
            Object obj = ref.get();
            
            if (obj == null) {
                // 软引用已被清理
                softCache.remove(entry.getKey());
                removedCount++;
            } else {
                // 检查是否需要清理
                if (shouldEvictObject(entry.getKey(), obj)) {
                    softCache.remove(entry.getKey());
                    freedMemory += estimateObjectSize(obj);
                    removedCount++;
                }
            }
        }
        
        totalMemoryUsed.addAndGet(-freedMemory);
        System.out.println("✅ 缓存清理完成: 移除" + removedCount + "个对象, 释放" + (freedMemory / 1024) + "KB内存");
    }
    
    /**
     * 检查内存压力
     */
    public static boolean isMemoryPressureHigh() {
        try {
            long usedMemory = memoryBean.getHeapMemoryUsage().getUsed();
            long maxMemory = memoryBean.getHeapMemoryUsage().getMax();
            
            if (maxMemory > 0) {
                double memoryUsagePercent = (double) usedMemory / maxMemory * 100;
                return memoryUsagePercent > MEMORY_WARNING_THRESHOLD;
            }
        } catch (Exception e) {
            System.err.println("检查内存压力失败: " + e.getMessage());
        }
        
        return false;
    }
    
    /**
     * 获取内存使用情况
     */
    public static String getMemoryStats() {
        try {
            long usedMemory = memoryBean.getHeapMemoryUsage().getUsed();
            long maxMemory = memoryBean.getHeapMemoryUsage().getMax();
            
            double memoryUsagePercent = maxMemory > 0 ? (double) usedMemory / maxMemory * 100 : 0;
            
            return String.format(
                "内存使用: %dMB/%dMB (%.1f%%), 缓存: %dKB, 命中率: %.1f%%",
                usedMemory / 1024 / 1024,
                maxMemory / 1024 / 1024,
                memoryUsagePercent,
                totalMemoryUsed.get() / 1024,
                getCacheHitRate()
            );
        } catch (Exception e) {
            return "内存统计获取失败: " + e.getMessage();
        }
    }
    
    /**
     * 获取缓存命中率
     */
    public static double getCacheHitRate() {
        long hits = cacheHits.get();
        long misses = cacheMisses.get();
        long total = hits + misses;
        
        return total > 0 ? (double) hits / total * 100 : 0;
    }
    
    /**
     * 估算对象大小
     */
    private static long estimateObjectSize(Object obj) {
        if (obj == null) return 0;
        
        // 简单的对象大小估算
        if (obj instanceof byte[]) {
            return ((byte[]) obj).length;
        } else if (obj instanceof String) {
            return ((String) obj).length() * 2; // UTF-16字符
        } else if (obj instanceof java.awt.image.BufferedImage) {
            java.awt.image.BufferedImage img = (java.awt.image.BufferedImage) obj;
            return img.getWidth() * img.getHeight() * 4; // ARGB
        } else {
            // 默认估算
            return 1024; // 1KB
        }
    }
    
    /**
     * 判断是否应该清理对象
     */
    private static boolean shouldEvictObject(String key, Object obj) {
        // 清理策略：优先清理大对象
        long size = estimateObjectSize(obj);
        return size > 1024 * 1024; // 大于1MB的对象
    }
    
    /**
     * 启动定时清理任务
     */
    private static void startCleanupTask() {
        cleanupExecutor.scheduleAtFixedRate(() -> {
            try {
                // 检查内存压力
                if (isMemoryPressureHigh()) {
                    System.out.println("⚠️ 检测到高内存压力，执行清理...");
                    cleanupCache();
                }
                
                // 定期清理过期缓存
                cleanupExpiredCache();
                
            } catch (Exception e) {
                System.err.println("定时清理任务失败: " + e.getMessage());
            }
        }, CLEANUP_INTERVAL_MINUTES, CLEANUP_INTERVAL_MINUTES, TimeUnit.MINUTES);
    }
    
    /**
     * 清理过期缓存
     */
    private static void cleanupExpiredCache() {
        // 清理已被GC的软引用
        softCache.entrySet().removeIf(entry -> entry.getValue().get() == null);
    }
    
    /**
     * 强制垃圾回收
     */
    public static void forceGarbageCollection() {
        System.out.println("🗑️ 执行强制垃圾回收...");
        
        long beforeMemory = memoryBean.getHeapMemoryUsage().getUsed();
        
        System.gc();
        
        try {
            Thread.sleep(1000); // 等待GC完成
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        
        long afterMemory = memoryBean.getHeapMemoryUsage().getUsed();
        long freedMemory = beforeMemory - afterMemory;
        
        System.out.println("✅ 垃圾回收完成，释放内存: " + (freedMemory / 1024 / 1024) + "MB");
    }
    
    /**
     * 优化内存使用
     */
    public static void optimizeMemory() {
        System.out.println("🔧 开始内存优化...");
        
        // 1. 清理缓存
        cleanupCache();
        
        // 2. 强制垃圾回收
        forceGarbageCollection();
        
        // 3. 重置统计
        cacheHits.set(0);
        cacheMisses.set(0);
        totalMemoryUsed.set(0);
        
        System.out.println("✅ 内存优化完成");
    }
    
    /**
     * 关闭管理器
     */
    public static void shutdown() {
        try {
            cleanupExecutor.shutdown();
            if (!cleanupExecutor.awaitTermination(5, TimeUnit.SECONDS)) {
                cleanupExecutor.shutdownNow();
            }
            
            // 清理所有缓存
            softCache.clear();
            totalMemoryUsed.set(0);
            
            System.out.println("🔌 内存管理器已关闭");
        } catch (Exception e) {
            System.err.println("关闭内存管理器失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取缓存统计
     */
    public static String getCacheStats() {
        int activeCacheSize = 0;
        int totalCacheSize = softCache.size();
        
        for (SoftReference<Object> ref : softCache.values()) {
            if (ref.get() != null) {
                activeCacheSize++;
            }
        }
        
        return String.format(
            "缓存统计: 总数=%d, 活跃=%d, 已清理=%d, 命中率=%.1f%%",
            totalCacheSize, activeCacheSize, totalCacheSize - activeCacheSize, getCacheHitRate()
        );
    }
}
